package com.scholarship.common.config;

import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.lang.reflect.Method;
import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * 线程池配置
 * @Author Z.J.H
 * @create 2021/8/26 9:59
 */
@Configuration
public class AsyncConfig {

    //核心线程数
    private int corePoolSize = 5;
    //最大线程数
    private int maxPoolSize = 20;
    //线程空闲时间
    private int keepAliveSeconds = 60 * 10;
    //线程对象的名字前缀
    private String threadNamePrefix = "my-Thread";
    //任务队列的容量
    private int queueCapacity = 5;

    @Bean("asyncExecutor")
    public Executor getAsyncExecutor() {
        ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
        //设置核心线程数
        taskExecutor.setCorePoolSize(corePoolSize);
        //设置最大线程数
        taskExecutor.setMaxPoolSize(maxPoolSize);
        //设置线程空闲时间
        taskExecutor.setKeepAliveSeconds(keepAliveSeconds);
        //设置线程对象的名字前缀
        taskExecutor.setThreadNamePrefix(threadNamePrefix);
        //设置缓存队列的容量
        taskExecutor.setQueueCapacity(queueCapacity);
        //设置拒绝处理的策略(当线程池无法处理新的任务时,该执行什么策略)
        taskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        //new ThreadPoolExecutor.CallerRunsPolicy() 该策略为选择调用者线程进行处理
        //new ThreadPoolExecutor.AbortPolicy() 该策略为丢弃任务并抛出RejectedExecutionException异常(不设置时默认此策略)
        //new ThreadPoolExecutor.DiscardPolicy() 该策略为丢弃任务,但是不抛异常
        //new ThreadPoolExecutor.DiscardOldestPolicy() 该策略为丢弃队列最前面的任务,然后重新尝试执行任务
        //初始化线程池
        taskExecutor.initialize();
        return taskExecutor;
    }

    //异常任务执行过程中的错误处理
    @Bean
    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
        return new AsyncUncaughtExceptionHandler() {
            @Override
            public void handleUncaughtException(Throwable throwable, Method method, Object... objects) {

            }
        };
    }
}
